package nl.windgazer.arachne.services.externalsource;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Scanner;

public class HtmlManagedContent implements ManagedContent {

	private static final String BODY_START = "<body";
	private static final String BODY_END = "</body";
	private static final String SCRIPT_START = "<script";
	private static final String SCRIPT_END = "</script";
	private static final String STYLE_START = "<style";
	private static final String STYLE_END = "</style";
	private static final String LINK_START = "<link";

	private boolean recordingBody = false;
	private boolean recordingScript = false;
	private boolean recordingStyle = false;

	private final StringBuilder body = new StringBuilder();
	private final StringBuilder script = new StringBuilder();
	private final StringBuilder style = new StringBuilder();
	private final ArrayList<String> scripts = new ArrayList<String>();
	private final ArrayList<String> styles = new ArrayList<String>();
	private final String filePath;
	private final String basePath;

	public HtmlManagedContent(File source, String filePath, String basePath) throws FileNotFoundException {
		this.filePath = filePath;
		this.basePath = basePath;
		if (source.exists()) {
			Scanner parser = new Scanner(source, "UTF-8");
			while (parser.hasNextLine()) {
				parseLine(parser.nextLine());
			}
			parser.close();//Clean up
		}
	}

	private void parseLine(String line) {
		//Style and script blocks will get rendered in content-block if they exist...
		if (recordingBody) {
			if (line.contains(BODY_END)) {
				recordingBody = false;
			} else {
				body.append(line);
				body.append('\n');
			}
			return;
		}
		if (recordingStyle) {
			if (line.contains(STYLE_END)) {
				recordingStyle = false;
			} else {
				style.append(line);
				body.append('\n');
			}
			return;
		}
		if (recordingScript) {
			if (line.contains(SCRIPT_END)) {
				recordingScript = false;
			} else {
				script.append(line);
				body.append('\n');
			}
			return;
		}
		recordingBody = line.contains(BODY_START);
		recordingScript = line.contains(SCRIPT_START);
		recordingStyle = line.contains(STYLE_START);
		if (recordingScript) {
			if (line.contains("src")) {
				int start = line.indexOf("src") + 5;
				int end = line.indexOf('"', start + 1);
				scripts.add(line.substring(start, end));
				recordingScript = false;
			}
		}
		if (line.contains(LINK_START)) {
			if (line.contains("type=\"text/css\"") && line.contains("href")) {
				int start = line.indexOf("href") + 6;
				int end = line.indexOf('"', start + 1);
				styles.add(line.substring(start, end));
			}
		}
	}

	public String getContent() {
		return body.toString();
	}

	public String getScriptBlock() {
		return script.toString();
	}

	public Collection<String> getScripts() {
		return scripts;
	}

	public String getStyleBlock() {
		return style.toString();
	}

	public Collection<String> getStyles() {
		return styles;
	}

	public String getUID() {
		return filePath;
	}

	public void setContent(String content) {
		body.setLength(0);
		body.trimToSize();
		body.append(content);
	}

	public void setScriptBlock(String script) {
		this.script.setLength(0);
		this.script.trimToSize();
		if (script !=null) this.script.append(script);
	}

	public void setStyleBlock(String style) {
		this.style.setLength(0);
		this.style.trimToSize();
		if (style != null) this.style.append(style);
	}

	public String getBaseURL() {
		return basePath;
	}

}
